package managementSystem;

import java.util.*;
import java.util.stream.Collectors;

@SuppressWarnings({"unchecked", "DuplicatedCode"})
public class ManagementSystem {
    private DataBase dataBase = new DataBase();
    private HashMap<String, String> map = new HashMap<>(){{
        put("姓名", "name");
        put("性别", "sex");
        put("民族", "nationality");
        put("出生", "born");
        put("住址", "address");
        put("身份证号", "identity");
        put("学号", "studentId");
        put("学院", "college");
        put("专业", "major");
        put("班级", "classes");
        put("成绩", "grades");
        put("班主任", "headTeacher");
    }};

    public Boolean initialization(ArrayList<HashMap<String, Object>> data){
        Boolean flag = true;
        for(HashMap<String, Object> value : data){
            flag &= this.dataBase.create("Student", value) != null;
        }
        return flag;
    }

    public String create(){
        return this.dataBase.create("Student", this.createData());
    }

    public Number delete(){
        return this.dataBase.delete("Student", this.createWhere());
    }

    public Number update(){
        return this.dataBase.update("Student", this.createWhere(), this.createData());
    }

    public Object get(){
        return this.dataBase.getItem("Student", this.createWhere());
    }

    public HashMap<String, Object> getList(){
        return this.dataBase.getRecords("Student", null);
    }

    public void statistics(){
        HashMap<String, Object> data = this.getList();
        HashMap<String, Number> total = new HashMap<>();
        HashMap<String, Number> average = new HashMap<>();
        HashMap<String, Number> passingRate = new HashMap<>();
        ArrayList<HashMap<String, Object>> students = (ArrayList<HashMap<String, Object>>)data.get("data");
        //统计各科总成绩
        for(HashMap<String, Object> value : students){
            HashMap<String, Number> grades = (HashMap<String, Number>)value.get("grades");
            if(grades != null){
                for(String key : grades.keySet()){
                    Number o = total.get(key);
                    Number val = grades.get(key);
                    total.put(key, o != null ? (o.doubleValue() + val.doubleValue()) : val.doubleValue());
                }
            }
        }
        //统计各科平均成绩
        for(String key : total.keySet()){
            average.put(key, total.get(key).doubleValue() / students.size());
        }
        //统计各科及格率
        for(String key : total.keySet()){
            Number pass = 0;
            for(HashMap<String, Object> value : students){
                HashMap<String, Number> grades = (HashMap<String, Number>)value.get("grades");
                Number grade = grades.get(key);
                if(grade != null && grade.doubleValue() >= 60){
                    pass = pass.doubleValue() + 1;
                }
            }
            passingRate.put(key, pass.doubleValue() / students.size());
        }
        //成绩排名
        students.sort((o1, o2) -> {
            HashMap<String, Number> grades1 = (HashMap<String, Number>)o1.get("grades");
            HashMap<String, Number> grades2 = (HashMap<String, Number>)o2.get("grades");
            double totalGrades1 = 0, totalGrades2 = 0;
            if(grades1 != null){
                for(String key : grades1.keySet()){
                    totalGrades1 += grades1.get(key).doubleValue();
                }
            }
            if(grades2 != null){
                for(String key : grades2.keySet()){
                    totalGrades2 += grades2.get(key).doubleValue();
                }
            }
            return (int)(totalGrades2 - totalGrades1);
        });
        //分班
        Map<Object, List<HashMap<String, Object>>> studentsByClass = students.stream().collect(Collectors.groupingBy((e) -> {
            return (String) e.get("college") + (String) e.get("major") + (String) e.get("classes");
        }));
        System.out.println("各科总成绩：");
        System.out.println(total);
        System.out.println("各科平均成绩：");
        System.out.println(average);
        System.out.println("各科及格率：");
        System.out.println(passingRate);
        System.out.println("排名(降序)：");
        for(Object key : studentsByClass.keySet()){
            System.out.println("班级：" + key);
            List<HashMap<String, Object>> value = studentsByClass.get(key);
            for(HashMap<String, Object> e : value){
                System.out.println(e);
            }
            System.out.println();
        }
    }

    private ArrayList<HashMap<String, Object>> createWhere(){
        String key, rel, val;
        Scanner scanner = new Scanner(System.in);
        ArrayList<HashMap<String, Object>> where = new ArrayList<>();
        System.out.println("查询指令：eq、neq、lt、lte、gt、gte、search");
        System.out.println("字段名：" + this.map.keySet());
        System.out.println("请输入查询条件(姓名\\neq\\n梁俊华\\n)输入“#”号终止：");
        for(int i = 0; ;i++){
            System.out.println("条件" + (i + 1) + "：");
            key = scanner.nextLine();
            if(key.equals("#")){
                break;
            }
            rel = scanner.nextLine();
            val = scanner.nextLine();
            HashMap<String, Object> e = new HashMap<>();
            e.put("key", this.map.get(key) != null ? this.map.get(key) : key);
            e.put("rel", rel);
            e.put("val", val);
            where.add(e);
        }
        return where;
    }

    private HashMap<String, Object> createData(){
        String in;
        Scanner scanner = new Scanner(System.in);
        HashMap<String, Object> data = new HashMap<>();
        System.out.println("字段名：" + this.map.keySet());
        System.out.println("请输入学生信息(姓名：梁俊华)输入”#“号终止：");
        while (!(in = scanner.nextLine()).equals("#")){
            String[] e = in.split("：");
            String key = this.map.get(e[0]), val = e.length > 1 ? e[1] : null;
            if(key != null && key.equals("grades")){
                data.put(key, this.createGrades());
                continue;
            }
            data.put(key != null ? key : e[0], e[1]);
        }
        return data;
    }

    private HashMap<String, Number> createGrades(){
        String in;
        Scanner scanner = new Scanner(System.in);
        HashMap<String, Number> data = new HashMap<>();
        System.out.println("请输入学生成绩(语文：100)输入”#“号终止：");
        while (!(in = scanner.nextLine()).equals("#")){
            String[] e = in.split("：");
            Number val = Double.parseDouble(e[1]);
            if(val.doubleValue() < 0 || val.doubleValue() > 100){
                System.out.println("成绩取值错误（0<=成绩<=100）");
                continue;
            }
            data.put(e[0], val);
        }
        return data;
    }
}
